package rolesystem.examples.jade.auction.bidder;

import rolesystem.core.*;
import rolesystem.roles.auction.*;

import java.io.Serializable;

/**
 * This class represents a possible behaviour for bidder of an English auction.
 * It is designed to be used by BidderSL.
 */
public abstract class BidderEng
{
	/**
	 * Tries to win the auction.
	 * @param registration Registration assigned to bidder.
	 * @param auctioneer Auctioneer identifier.
	 * @param budget Available money.
	 * @return The price to pay, or null if the auction
	 * has been won by someone else.
	 */
	public static Price go(RoleRegistration registration, int auctioneer,
		Price budget) throws RoleException
	{
		RoleEvent event;
		Price myBid=new Price(0,"Euro");
		Price price=null;
		boolean again1;
		boolean again2;

		// Loop until the auction is over or I cannot bid anymore.
		again1=true;
		do
		{
			registration.doAction(Bidder.
				askSituation(auctioneer));

			// Loop until a suitable reply is received.
			again2=true;
			do
			{
				event=registration.listen();
				if(event.getSender()==auctioneer)
					// A do...while(false) block is used, so a break
					// causes the exit from this block.
					do
					{
						if(Bidder.KE_notifySituation.match(event))
						{
							Situation tmp=(Situation)event.getContent();
							if( tmp.getWinnBidder()!=registration.whoAmI() )
							{
								// If possible, I have to bid.
								myBid=tmp.getPrice();
								if( myBid.getCurrency().equals(budget.getCurrency()) &&
									myBid.getAmount()<=budget.getAmount() )
									registration.doAction(Bidder.
										bid(auctioneer, myBid));
								else
									again1=false;
							}
							again2=false;
							break;
						}
						if(Bidder.KE_auctionOver.match(event))
						{
							again1=false;
							again2=false;
							break;
						}
						if(Bidder.KE_youWon.match(event))
						{
							Price tmp=(Price)event.getContent();
							if( myBid.getCurrency().equals(tmp.getCurrency()) &&
								myBid.getAmount()==tmp.getAmount() )
								price=myBid;
							again1=false;
							again2=false;
							break;
						}
						// Other events are ignored.
					} while(false);
			} while(again2);

			// A suitable reply is received.
		} while(again1);

		// The auction is over.
		return price;
	}
}
